import SvgIcon from '@/components/SvgIcon/index.vue'
import { SupportMethodType } from '@/types/knife4j'
import { App, Component, Plugin } from 'vue'

/**
 * 提取对象属性值
 *
 * @param arr 待提取对象数组
 * @param field 待提取的属性名
 * @return [] 提取后的数组
 * @author: 沐雨
 * @time: 2020-04-01
 * @Last Modified by: 沐雨
 * @Last Modified time: 2022-07-12 12:32:14
 */
export function extract<T, U extends keyof T>(arr: T[], field: U): T[U][] {
  return arr.map((item) => item[field]).filter((x) => x !== undefined)
}

/**
 * 提取对象属性值
 * 提取对象属性值
 *
 * @param obj 待提取对象
 * @param key 待提取的属性名
 * @returns 提取后的值
 * @author 沐雨
 * @time 2020-07-07 20:20:37
 */
export function getAttribute<T, F extends keyof T>(obj: T, key: F): T[F] {
  return obj[key]
}

/**
 * 根据属性名获取对象属性值
 *
 * @param data 待提取的数据
 * @param keys 待提取的属性名
 * @param join 是否需要拼接，默认不拼接
 * @param conjunction 分隔符，默认为空
 * @returns 拼接后的结果
 */
export function getValuesFromObjectByKes<T extends Record<string, any>, K extends keyof T>(
  data: T,
  keys: K[],
  join?: boolean,
  conjunction?: string
): string | string[] {
  if (typeof keys === 'string') {
    return data[keys]
  }
  const result = keys.map((k) => data[k]).filter((x) => x !== '市辖区')
  return join ? result.join(conjunction ?? '') : result
}

/**
 * 获取函数返回值类型
 */
export type GetFunReturnType<T> = T extends (...args: any[]) => infer R ? R : T

export const withInstall = <T extends Component>(component: T, alias?: string) => {
  const comp = component as any
  comp.install = (app: App) => {
    app.component(comp.name || comp.displayName, component)
    if (alias) {
      app.config.globalProperties[alias] = component
    }
  }
  return component as T & Plugin
}

export function isJson(str: string): boolean {
  try {
    const obj = JSON.parse(str)
    return typeof obj === 'object' && obj
  } catch (e) {
    // console.log(`error：${str}!!!${e}`);
    return false
  }
}

export function renderSvgIcon(name: string, size?: number) {
  return h(SvgIcon, {
    name,
    size: size ?? 18
  })
}

export function renderMethodIcon(name: string) {
  const methodUpperCase = name.toUpperCase() as SupportMethodType
  return h(
    'span',
    {
      style: {
        'display': 'inline-block',
        'width': '38px',
        'font-size': '12px',
        'font-weight': 'bold'
      },
      class: ['k-api', `k-api-${name}`]
    },
    {
      default: () => (name !== 'post' ? methodUpperCase.substring(0, 3) : methodUpperCase)
    }
  )
}

export function objArray2obj(map?: [string, any]) {
  const obj = Object.create(null)
  if (!map) return obj
  const [k, v] = map
  obj[k] = v
  return obj
}

export function getBlobLength(str: string) {
  let len = 0
  for (let i = 0; i < str.length; i++) {
    len += str.charCodeAt(i) > 127 || str.charCodeAt(i) === 94 ? 2 : 1
  }
  return len
}

export function formatterTime(time: number): string {
  if (time > 1000) {
    // 超过1秒钟
    const sec = Math.floor(time / 1000).toFixed(2)
    return `${sec} s`
  }
  return `${time} ms`
}

export function formatterByteSize(size = 0): string {
  const kbSize = Number((size / 1024).toFixed(2))
  const mbSize = Number((size / 1024 / 1024).toFixed(2))
  if (kbSize > 1) {
    return `${size} KB`
  }
  if (mbSize > 1) {
    return `${size} MB`
  }
  return `${size} B`
}
